package com.bugpool.leilema.tc.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bugpool.leilema.freamwork.datascope.DataScopeConstants;
import com.bugpool.leilema.freamwork.satoken.SaTokenUtil;
import com.bugpool.leilema.freamwork.satoken.StpInterfaceImpl;
import com.bugpool.leilema.tc.bean.entity.SysRole;
import com.bugpool.leilema.tc.bean.entity.SysRoleDept;
import com.bugpool.leilema.tc.bean.entity.SysUser;
import com.bugpool.leilema.tc.bean.enums.StatusEnum;
import com.bugpool.leilema.tc.bean.req.BaseReq;
import com.bugpool.leilema.tc.bean.req.RoleDataScopeReq;
import com.bugpool.leilema.tc.bean.req.RoleMenuReq;
import com.bugpool.leilema.tc.bean.vo.SysUserVo;
import com.bugpool.leilema.tc.mapper.RoleDeptMapper;
import com.bugpool.leilema.tc.mapper.RoleMapper;
import com.bugpool.leilema.tc.mapper.UserMapper;
import com.bugpool.leilema.tc.mapper.UserRoleMapper;
import com.bugpool.leilema.tc.service.RoleService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @Author wh
 * @Description
 * @Date 2023/3/2 18:11
 * @Version 1.0
 **/
@Service
public class RoleServiceImpl implements RoleService {

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private RoleDeptMapper roleDeptMapper;

    @Override
    public Page<SysRole> selectPage(BaseReq baseReq) {

        Page<SysRole> page = new Page<>(baseReq.getCurrent(), baseReq.getSize());
        //判断是否是超级管理员
        SysUserVo user = SaTokenUtil.getUser();
        if (user.isAdmin()) {
            //获取所有的角色列表
            return roleMapper.selectPage(page, null);
        } else {
            page = roleMapper.selectPageByUser(page, user.getUserId());
            return page;
        }

    }

    @Override
    public List<SysRole> selectList() {
        SysUserVo user = SaTokenUtil.getUser();
        if (user.isAdmin()) {
            return roleMapper.selectList(null);
        }
        return roleMapper.selectListByUser(user.getUserId());
    }

    @Override
    public Boolean addRole(SysRole sysRole) {
        roleMapper.insert(sysRole);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delIds(List<Long> ids) {
        //根据角色id 判断下面是否有用户
        Integer count = userRoleMapper.getUserCountIdByRoleIds(ids);
        if (count >= 1) {
            throw new RuntimeException("要删除的角色下 关联着用户");
        }
        roleMapper.deleteBatchIds(ids);
        roleMapper.deleteRoleMenuIds(ids);
        return true;
    }

    @Override
    public Boolean updateRole(SysRole sysRole) {
        roleMapper.updateById(sysRole);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateRoleMenu(RoleMenuReq roleMenuReq) {
        //删除 原有的权限 与菜单表关联的关系
        roleMapper.deleteRoleMenuIds(Arrays.asList(roleMenuReq.getRoleId()));
        //新增 新的菜单角色关系
        roleMapper.insertRoleMenu(roleMenuReq.getRoleId(), roleMenuReq.getMenuIds());
        return true;
    }

    @Override
    public Boolean updateRoleStatus(Long roleId, String status) {
        //如果是启用直接更新
        roleMapper.updateRoleStatus(roleId, status);
        if (StatusEnum.getStatusEnum(status) == StatusEnum.DISABLE) {
            //查询出跟 该角色关联的用户id
            List<Long> userIds = userRoleMapper.getUserIdsByRoleId(roleId);
            //踢人下线
            userIds.forEach(t -> StpUtil.logout(t));
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateRoleDataScope(RoleDataScopeReq roleDataScopeReq) {
        roleMapper.updateRoleDataScope(roleDataScopeReq);
        //如果是自定义数据权限 更新
        if (DataScopeConstants.DATA_SCOPE_CUSTOM.equals(roleDataScopeReq.getDataScope())) {
            roleDeptMapper.deleteByRoleId(roleDataScopeReq.getRoleId());
            //更新绑定关系
            List<Long> deptIds = roleDataScopeReq.getDeptIds();
            SysRoleDept roleDept = new SysRoleDept();
            roleDept.setRoleId(roleDataScopeReq.getRoleId());
            Optional.ofNullable(deptIds).ifPresent(deptIdList -> {
                deptIdList.stream().forEach(deptId -> {
                    roleDept.setDeptId(deptId);
                    //添加新的关系
                    roleDeptMapper.insert(roleDept);
                });
            });
        }
        return true;
    }
}
